<template>
  <div
    class="comment-item"
    :class="{
      active: activeCommentId === comment.id,
      resolved: comment.isResolved,
    }"
    @click="handleSelect"
  >
    <div class="comment-header">
      <div class="comment-author">
        <div class="author-avatar-wrapper">
          <img
            v-if="comment.author.avatar"
            :src="comment.author.avatar"
            :alt="comment.author.name"
            class="author-avatar"
          />
          <div v-else class="author-avatar-placeholder">
            {{ comment.author.name.charAt(0).toUpperCase() }}
          </div>
        </div>
        <div class="author-info">
          <span class="author-name">{{ comment.author.name }}</span>
          <span class="comment-time">{{ formatTime(comment.createdAt) }}</span>
        </div>
      </div>
      <div class="comment-status">
        <span v-if="comment.isResolved" class="resolved-badge">已解决</span>
      </div>
    </div>
    <div class="comment-body">
      <div
        class="comment-content"
        v-html="comment.content || '（无内容）'"
      ></div>
      <CommentList
        v-if="comment.replies?.length"
        ref="commentListRef"
        :replies="comment.replies"
        :comment-id="commentId || comment.id"
        :current-user-id="currentUserId"
        :highlighted-reply-id="highlightedReplyId"
        :is-resolved="comment.isResolved"
        @reply="handleReplyToReply"
        @quote="handleQuoteReply"
        @quote-click="handleQuoteClick"
        @updated="handleRepliesUpdated"
      />
    </div>
    <div v-if="!comment.isResolved" class="comment-footer">
      <div class="comment-reply-input">
        <!-- 引用预览 -->
        <div v-if="currentQuote" class="quote-preview">
          <div class="quote-preview-content">
            <span class="quote-preview-text">{{
              getPlainText(currentQuote.content)
            }}</span>
          </div>
          <el-button
            size="small"
            text
            class="quote-preview-close"
            @click="clearQuote"
          >
            <i class="i-ri-close-line"></i>
          </el-button>
        </div>
        <el-input
          ref="replyInputRef"
          v-model="replyText"
          type="textarea"
          :rows="2"
          :placeholder="
            comment.isResolved
              ? '已解决的批注不可回复'
              : currentQuote
              ? '输入回复内容...'
              : '添加回复...'
          "
          :disabled="comment.isResolved"
          @keydown.ctrl.enter="handleAddReply"
          @keydown.meta.enter="handleAddReply"
          @input="handleInput"
        />
        <!-- @提及列表 -->
        <transition name="fade">
          <div
            v-if="showMentionList && mentionList.length > 0"
            class="mention-list"
          >
            <div class="mention-list-header">
              <span class="mention-list-title">@提及</span>
            </div>
            <div class="mention-list-content">
              <DynamicVirtualList
                :data="mentionList"
                :estimated-height="50"
                :buffer="3"
                item-key="id"
                :reset-scroll-on-data-change="false"
              >
                <template #default="{ item }">
                  <div
                    class="mention-item"
                    @click="selectMention(item as { id: string; name: string })"
                  >
                    <div class="mention-avatar">
                      {{
                        (item as { id: string; name: string }).name
                          .charAt(0)
                          .toUpperCase()
                      }}
                    </div>
                    <div class="mention-info">
                      <span class="mention-name">{{
                        (item as { id: string; name: string }).name
                      }}</span>
                      <span class="mention-hint">点击选择</span>
                    </div>
                  </div>
                </template>
              </DynamicVirtualList>
            </div>
          </div>
        </transition>
        <div class="comment-footer-actions">
          <el-button
            size="small"
            type="primary"
            :disabled="comment.isResolved"
            @click="handleAddReply"
          >
            回复
          </el-button>
          <el-button size="small" text @click.stop="handleResolve">
            {{ comment.isResolved ? "取消解决" : "解决" }}
          </el-button>
          <el-popconfirm
            v-if="!comment.isResolved"
            title="确定要删除这条批注吗？"
            confirm-button-text="确定"
            cancel-button-text="取消"
            @confirm="handleDelete"
          >
            <template #reference>
              <el-button size="small" text type="danger" @click.stop>
                删除
              </el-button>
            </template>
          </el-popconfirm>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {
  computed,
  inject,
  ref,
  nextTick,
  onBeforeUnmount,
  type Ref,
} from "vue";
import { ElInput } from "element-plus";
import type { Editor } from "@tiptap/vue-3";
import CommentList from "./CommentList.vue";
import { DynamicVirtualList } from "../virtual/index";
import type { Comment, CommentReply, CommentQuote } from "../../types/comment";
import { commentActions } from "../../store/comment";
import { getRelativeTime } from "../../utils";

defineOptions({
  name: "CommentItem",
});

const props = defineProps<{
  comment: Comment;
  activeCommentId: string | null;
  commentId?: string; // 可选的批注ID，如果不提供则使用 comment.id
  currentUserId?: string; // 当前用户ID
}>();

const emit = defineEmits<{
  (e: "select", commentId: string): void;
  (e: "scroll-to-item", commentId: string): void;
  (e: "scroll-to-reply", replyId: string): void;
}>();

const editor = inject<Ref<Editor>>("editor");

const replyText = ref("");
const replyInputRef = ref<InstanceType<typeof ElInput>>();
const commentListRef = ref<InstanceType<typeof CommentList>>();
const currentQuote = ref<CommentQuote | null>(null);
const mentionList = ref<Array<{ id: string; name: string }>>([]);
const showMentionList = ref(false);
const mentionSearchText = ref("");
const highlightedReplyId = ref<string | undefined>(undefined);

// 获取批注ID（优先使用传入的commentId，否则使用comment.id）
const commentId = computed(() => props.commentId || props.comment.id);

// 获取当前用户ID（默认值，实际应该从用户系统获取）
const currentUserId = computed(() => props.currentUserId || "current-user-id");

// 格式化时间（保留用于其他地方可能的使用）
const formatTime = (time: string) => {
  return getRelativeTime(time);
};

// 选择评论
const handleSelect = () => {
  emit("select", commentId.value);
  emit("scroll-to-item", commentId.value);
};

// 解决/取消解决
const handleResolve = () => {
  const currentUserId = "current-user-id"; // TODO: 获取当前用户ID
  commentActions.toggleResolve(commentId.value, currentUserId, editor?.value);
};

// 删除评论
const handleDelete = () => {
  commentActions.deleteComment(commentId.value, editor?.value);
};

// 添加回复
const handleAddReply = () => {
  // 已解决的批注不可回复
  if (props.comment.isResolved) {
    return;
  }
  const content = replyText.value.trim();
  if (!content) return;

  const reply: CommentReply = {
    id: `reply-${Date.now()}`,
    content,
    author: {
      id: currentUserId.value,
      name: "当前用户", // TODO: 获取当前用户名称
    },
    createdAt: new Date().toISOString(),
    likeCount: 0,
    dislikeCount: 0,
    likes: [],
    quote: currentQuote.value || undefined,
  };

  commentActions.addReply(commentId.value, reply);
  replyText.value = "";
  currentQuote.value = null;
  showMentionList.value = false;
};

// 处理引用回复
const handleQuoteReply = (
  replyId: string,
  authorName: string,
  content: string
) => {
  // 已解决的批注不能使用引用功能
  if (props.comment.isResolved) return;
  // 设置引用
  currentQuote.value = {
    replyId,
    authorName,
    content,
  };
  // 聚焦到输入框
  nextTick(() => {
    replyInputRef.value?.focus();
  });
};

// 定时器引用，用于清理
let highlightTimer: ReturnType<typeof setTimeout> | null = null;

// 处理点击引用
const handleQuoteClick = async (replyId: string) => {
  // 清理之前的定时器
  if (highlightTimer) {
    clearTimeout(highlightTimer);
    highlightTimer = null;
  }

  // 高亮该回复
  highlightedReplyId.value = replyId;

  // 先滚动到批注项（确保批注项可见）
  emit("scroll-to-item", commentId.value);

  // 等待批注项滚动完成
  await new Promise((resolve) => {
    const timer = setTimeout(resolve, 300);
    // 如果组件卸载，清理定时器
    if (!isComponentMounted) {
      clearTimeout(timer);
    }
  });

  // 使用CommentList的scrollToReply方法
  if (commentListRef.value) {
    await commentListRef.value.scrollToReply(replyId);
  }

  // 3秒后取消高亮
  highlightTimer = setTimeout(() => {
    highlightedReplyId.value = undefined;
    highlightTimer = null;
  }, 3000);
};

// 组件挂载状态
let isComponentMounted = true;

// 组件卸载时清理定时器
onBeforeUnmount(() => {
  isComponentMounted = false;
  if (highlightTimer) {
    clearTimeout(highlightTimer);
    highlightTimer = null;
  }
});

// 清除引用
const clearQuote = () => {
  currentQuote.value = null;
};

// 获取纯文本内容
const getPlainText = (html: string) => {
  if (!html) return "";
  const div = document.createElement("div");
  div.innerHTML = html;
  const text = div.textContent || div.innerText || "";
  return text.length > 50 ? text.substring(0, 50) + "..." : text;
};

// 处理回复回复（点击回复按钮相当于@）
const handleReplyToReply = (_replyId: string, authorName: string) => {
  // 在输入框中添加@提及
  const currentText = replyText.value.trim();
  if (currentText && !currentText.endsWith(" ")) {
    replyText.value = `${currentText} @${authorName} `;
  } else {
    replyText.value = `@${authorName} `;
  }
  // 聚焦到输入框
  nextTick(() => {
    const textarea = replyInputRef.value?.textarea;
    if (textarea) {
      const newPos = replyText.value.length;
      textarea.setSelectionRange(newPos, newPos);
      replyInputRef.value?.focus();
    }
  });
};

// 处理输入（@功能）
const handleInput = (value: string) => {
  const textarea = replyInputRef.value?.textarea;
  if (!textarea) return;

  const cursorPos = textarea.selectionStart || 0;
  const textBeforeCursor = value.substring(0, cursorPos);
  const lastAtPos = textBeforeCursor.lastIndexOf("@");

  if (lastAtPos !== -1) {
    const textAfterAt = textBeforeCursor.substring(lastAtPos + 1);
    // 检查@后面是否有空格或换行，如果有则关闭提示
    if (!textAfterAt.match(/[\s\n]/)) {
      mentionSearchText.value = textAfterAt;
      showMentionList.value = true;
      // TODO: 根据mentionSearchText搜索用户列表
      // 这里应该从用户系统获取
      mentionList.value = [
        { id: "user1", name: "张三" },
        { id: "user2", name: "李四" },
        { id: "user3", name: "王五" },
      ].filter((user) => user.name.includes(mentionSearchText.value));
    } else {
      showMentionList.value = false;
    }
  } else {
    showMentionList.value = false;
  }
};

// 选择@用户
const selectMention = (user: { id: string; name: string }) => {
  const textarea = replyInputRef.value?.textarea;
  if (!textarea) return;

  const cursorPos = textarea.selectionStart || 0;
  const textBeforeCursor = replyText.value.substring(0, cursorPos);
  const lastAtPos = textBeforeCursor.lastIndexOf("@");
  const textAfterCursor = replyText.value.substring(cursorPos);

  if (lastAtPos !== -1) {
    const textBeforeAt = replyText.value.substring(0, lastAtPos);
    replyText.value = textBeforeAt + `@${user.name} ` + textAfterCursor;
    showMentionList.value = false;
    mentionSearchText.value = "";
    nextTick(() => {
      const newPos = textBeforeAt.length + user.name.length + 2;
      textarea.setSelectionRange(newPos, newPos);
      replyInputRef.value?.focus();
    });
  }
};

// 处理回复更新
const handleRepliesUpdated = () => {
  // 可以在这里触发重新渲染或其他逻辑
};
</script>

<style lang="scss" scoped>
.comment-item {
  padding: 16px;
  margin-bottom: 12px;
  border-radius: 8px;
  border: 2px solid transparent;
  background: #fafafa;
  transition: all 0.2s ease;
  cursor: pointer;

  &:hover {
    background: #f5f5f5;
  }

  &.active {
    border-color: var(--editor-primary-color, #1890ff);
    background: #ffffff;
  }

  &.resolved {
    opacity: 0.7;
  }
}

.comment-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 12px;
}

.comment-author {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
}

.author-avatar-wrapper {
  flex-shrink: 0;
}

.author-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  object-fit: cover;
}

.author-avatar-placeholder {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #ffffff;
  font-size: 14px;
  font-weight: 600;
}

.author-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}

.author-name {
  font-weight: 600;
  font-size: 14px;
  color: var(--editor-text-color);
  line-height: 1.4;
}

.comment-time {
  font-size: 12px;
  color: var(--comment-time-color);
  line-height: 1.4;
}

.comment-status {
  flex-shrink: 0;
}

.resolved-badge {
  display: inline-block;
  padding: 2px 8px;
  background: var(--comment-resolved-bg);
  color: var(--comment-resolved-color);
  font-size: 11px;
  border-radius: 12px;
  font-weight: 500;
}

.comment-body {
  margin-bottom: 12px;
}

.comment-content {
  font-size: 14px;
  line-height: 1.6;
  word-break: break-word;
  color: var(--editor-text-color);
  margin-bottom: 12px;

  :deep(p) {
    margin: 0 0 8px 0;
    &:last-child {
      margin-bottom: 0;
    }
  }

  :deep(ul),
  :deep(ol) {
    margin: 8px 0;
    padding-left: 20px;
  }
}

.comment-footer {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--comment-divider-color);
}

.comment-reply-input {
  margin-top: 8px;
  position: relative;
}

.comment-footer-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  flex-wrap: wrap;
}

.quote-preview {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  background-color: var(--comment-quote-background);
  border-radius: 4px;
  margin-bottom: 8px;
  font-size: 12px;
  transition: background-color 0.2s;
}

.quote-preview-content {
  flex: 1;
  min-width: 0;
  overflow: hidden;
}

.quote-preview-text {
  color: var(--comment-quote-text-color);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.5;
}

.quote-preview-close {
  flex-shrink: 0;
  margin-left: 8px;
  padding: 0;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  transition: background-color 0.2s;

  &:hover {
    background-color: var(--comment-item-hover-background);
  }
}

.mention-list {
  position: absolute;
  z-index: 1000;
  background: var(--comment-mention-bg);
  border: 1px solid var(--comment-mention-border);
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  margin-top: 4px;
  min-width: 240px;
  max-width: 300px;
  overflow: hidden;
}

.mention-list-header {
  padding: 8px 12px;
  background-color: var(--comment-mention-header-bg);
  border-bottom: 1px solid var(--comment-mention-border);
}

.mention-list-title {
  font-size: 12px;
  color: var(--comment-mention-text-color);
  font-weight: 500;
}

.mention-list-content {
  max-height: 200px;
  overflow-y: auto;

  // 虚拟列表容器样式
  :deep(.virtual-list-container) {
    max-height: 200px;
  }
}

.mention-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  cursor: pointer;
  transition: all 0.2s;
  border-bottom: 1px solid var(--comment-mention-divider);

  &:last-child {
    border-bottom: none;
  }

  &:hover {
    background-color: var(--comment-mention-item-hover-bg);
  }

  &:active {
    background-color: var(--comment-mention-item-active-bg);
  }
}

.mention-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #ffffff;
  font-size: 14px;
  font-weight: 600;
  flex-shrink: 0;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.mention-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}

.mention-name {
  font-size: 14px;
  color: var(--editor-text-color);
  font-weight: 500;
  line-height: 1.4;
}

.mention-hint {
  font-size: 11px;
  color: var(--comment-mention-text-color);
  line-height: 1.4;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.2s, transform 0.2s;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
  transform: translateY(-4px);
}
</style>
